package com.example.dingtalk.service.impl;

import cn.hutool.core.bean.BeanUtil;
import com.aliyun.dingtalkworkflow_1_0.models.GetProcessInstanceResponseBody;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.example.dingtalk.entity.dto.ExcelDto;
import com.example.dingtalk.entity.po.DingoaAccountsProcess;
import com.example.dingtalk.entity.po.DingoaSalesDetailProcess;
import com.example.dingtalk.entity.po.DingoaSalesProcess;
import com.example.dingtalk.mapper.DingoaAccountsProcessMapper;
import com.example.dingtalk.service.ExpenseProcessHandler;
import com.example.dingtalk.service.IDingoaAccountsProcessService;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.example.dingtalk.util.TextConstants;
import org.springframework.stereotype.Service;

import java.math.BigDecimal;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.time.LocalDate;
import java.time.LocalDateTime;
import java.time.ZoneId;
import java.time.format.DateTimeFormatter;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;
import java.util.Map;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
import java.util.stream.Collectors;

import static com.example.dingtalk.util.DingConstants.COMPLETED;
import static com.example.dingtalk.util.DingConstants.PENDING_APPROVAL;

/**
 * <p>
 * 应付账款流程表 服务实现类
 * </p>
 *
 * @author ckcool
 * @since 2024-08-08
 */
@Service
public class DingoaAccountsProcessServiceImpl extends ServiceImpl<DingoaAccountsProcessMapper, DingoaAccountsProcess> implements IDingoaAccountsProcessService, ExpenseProcessHandler {
    /**
     * 处理数据保存
     * @param instance
     * @param flag
     */
    @Override
    public void handle(GetProcessInstanceResponseBody.GetProcessInstanceResponseBodyResult instance, Boolean flag, String instanceId) throws ParseException {
        DingoaAccountsProcess payableprocess = new DingoaAccountsProcess();
        String title = instance.getTitle();
        payableprocess.setTitle(title);
        payableprocess.setApplicantDepartment(instance.getOriginatorDeptName());
        payableprocess.setVoucherColumn(instance.getBusinessId());
        //实例id
        payableprocess.setInstanceId(instanceId);
        if(instance.getStatus().equals("COMPLETED")) {
            payableprocess.setIsComplete("已完成");
        }else {
            payableprocess.setIsComplete("待审批");
        }
        List<GetProcessInstanceResponseBody.GetProcessInstanceResponseBodyResultFormComponentValues> componentValues = instance.getFormComponentValues();
        for (GetProcessInstanceResponseBody.GetProcessInstanceResponseBodyResultFormComponentValues componentValue : componentValues) {
            switch (componentValue.getName()) {
                case "付款事由":
                    payableprocess.setSummary(componentValue.getValue());
                    break;
                case "项目":
                    // 获取原始的字符串值
                    String originalValue = componentValue.getValue();
                    String cleanedValue = originalValue.replace("[", "").replace("]", "").replace("\"", "");
                    payableprocess.setProject(cleanedValue);
                    break;
                case "收款单位（个人）":
                    payableprocess.setRecipientName(componentValue.getValue());
                    break;
                case "收款人身份证号":
                    payableprocess.setRecipientIdNumber(componentValue.getValue());
                    break;
                case "收款单位（个人）银行账号":
                    payableprocess.setRecipientAccountNumber(componentValue.getValue());
                    break;
                case "收款单位（个人）开户行网点":
                    payableprocess.setReceivingBank(componentValue.getValue());
                    break;
                case "付款金额":
                    payableprocess.setCredit(new BigDecimal(componentValue.getValue()));
                    break;
                case "付款金额（元）":
                    payableprocess.setCredit(new BigDecimal(componentValue.getValue()));
                    break;
                case "币种":
                    payableprocess.setCurrency(componentValue.getValue());
                    break;
                case "店铺号":
                    payableprocess.setStoreNumber(componentValue.getValue());
                    break;
                case "付款公司":
                    if ("其他".equals(componentValue.getValue())) {
                        payableprocess.setPaymentBank("苏发国际");
                    } else {
                        payableprocess.setPaymentBank(componentValue.getValue());
                    }
                    break;
                default:
                    break;
            }
        }
        //截取title
        payableprocess.setDebitSubject("应付账款");
        payableprocess.setApplicant(extractApplicantFromTitle(title));
        //拉取时间
        payableprocess.setFetchDate(new Date());

        String createTimeString = instance.getCreateTime();
        LocalDateTime localDateTime = LocalDateTime.parse(createTimeString, DateTimeFormatter.ISO_DATE_TIME);
        Date createTime = Date.from(localDateTime.atZone(ZoneId.of("Asia/Shanghai")).toInstant());

        //创建时间
        payableprocess.setCreateTime(createTime);

        String finishTimeString = instance.getFinishTime();
        if(finishTimeString != null) {
            LocalDateTime localDate = LocalDateTime.parse(finishTimeString, DateTimeFormatter.ISO_DATE_TIME);
            Date finishTime = Date.from(localDate.atZone(ZoneId.of("Asia/Shanghai")).toInstant());
            //完成时间
            payableprocess.setFinishTime(finishTime);
        }

        //更新时间
        payableprocess.setUpdateTime(new Date());
        //System.out.println(payableprocess);
        // 存储到相应的表
        save(payableprocess);
    }


    /**
     * 根据标题提取申请人
     * @param title
     * @return
     */
    private String extractApplicantFromTitle(String title) {
        Pattern pattern = Pattern.compile(TextConstants.PATTERN);
        Matcher matcher = pattern.matcher(title);
        if (matcher.find()) {
            return matcher.group(1);
        } else {
            throw new IllegalArgumentException("Cannot extract applicant from title: " + title);
        }

    }


    @Override
    public List<ExcelDto> toExcelDto(String startDate, String endDate,Boolean flag) {
        List<DingoaAccountsProcess> payableprocesses = null;

        // 构建基础查询
        LambdaQueryWrapper<DingoaAccountsProcess> query = new LambdaQueryWrapper<DingoaAccountsProcess>()
                .eq(DingoaAccountsProcess::getIsComplete, PENDING_APPROVAL)
                .ge(DingoaAccountsProcess::getCreateTime, startDate)
                .le(DingoaAccountsProcess::getCreateTime, endDate);
        if (!flag){
            query.eq(DingoaAccountsProcess::getIsExporter, false);
        }
        payableprocesses = this.list(query);
        // 转换为 ExcelDto 列表
        List<ExcelDto> excelDtos = new ArrayList<>();
        return getExcelDtos(payableprocesses, excelDtos);
    }

    @Override
    public List<ExcelDto> toExcel(String startDate, String endDate,Boolean flag) {
        // 查询在指定日期范围内的数据并转换为 ExcelDto 列表
        // 假设 list() 方法会返回所有的 AccountsPayableprocess 对象
        List<DingoaAccountsProcess> payableprocessList = null;
        LambdaQueryWrapper<DingoaAccountsProcess> query = new LambdaQueryWrapper<>();
        query.eq(DingoaAccountsProcess::getIsComplete, COMPLETED);
        query.ge(DingoaAccountsProcess::getCreateTime, startDate);
        query.le(DingoaAccountsProcess::getCreateTime, endDate);
        if (!flag) {
            query.eq(DingoaAccountsProcess::getIsExporter, false);
        }
        payableprocessList = this.list(query);


        List<ExcelDto> excelDtos = new ArrayList<>();
        return getExcelDtos(payableprocessList, excelDtos);
    }

    private List<ExcelDto> getExcelDtos(List<DingoaAccountsProcess> payableprocessList, List<ExcelDto> excelDtos) {
        for (DingoaAccountsProcess payableprocess : payableprocessList) {
            ExcelDto excelDto = BeanUtil.copyProperties(payableprocess, ExcelDto.class);
            excelDto.setJournalProject(payableprocess.getDebitSubject());
            excelDto.setPaymentCompany(payableprocess.getPaymentBank());
            excelDto.setAccountingDepartment(payableprocess.getApplicantDepartment());
            excelDto.setAttributionDetails(payableprocess.getStoreNumber());
            payableprocess.setIsExporter(true);
            excelDtos.add(excelDto);
        }
        updateBatchById(payableprocessList);
        return excelDtos;
    }
}
